home *** CD-ROM | disk | FTP | other *** search
- ;****** Auto-Revision Header (do not edit) *******************************
- ;*
- ;* © This is Freeware (All rights are reserved by Peter Simons!)
- ;*
- ;* Filename : CpuClr.asm
- ;* Created on : 23-Jul-92
- ;* Created by : Peter Simons
- ;* Current revision : V3.100
- ;*
- ;*
- ;* Purpose: This program replaces the system-routine BltClear() with a
- ;* highly optimized 68020/30/40 routine.
- ;*
- ;*
- ;* V3.100 : released in: Kickstart-Magazin, Germany
- ;* Peter Simons (20-Okt-92)
- ;*
- ;* V3.005 : added a "40" in the version-string, if the SPECIAL40-flag
- ;* is set.
- ;*
- ;* V3.004 : rescuing registers before WaitBlit() is unnecessary :-)
- ;*
- ;* V3.003 : added special-68040-switch for safety (When set, the copyback
- ;* is flushed after the clear-loop.)
- ;*
- ;* V3.002 : didn't rescue the registers before jumping into WaitBlit()
- ;*
- ;* V3.001 : used the wrong address-register in the copy-routine for
- ;* long-aligned blocksize and word-aligned blockaddress
- ;* Thanks to Stefan Thielscher for reporting.
- ;*
- ;* V3.000 : The new "perfect" version has been sold to the Kickstart-
- ;* computer-magazin, Germany. Thanks for allowing me to
- ;* distribute it via Fred Fish!
- ;* Peter Simons (17-Okt-92)
- ;*
- ;* V2.104 : Fixed nasty bug, that caused NewBltClear() to crash with very
- ;* small block-sizes.
- ;* Thanks to Stefan Thielscher for reporting.
- ;*
- ;* V2.103 : Rewrote NewBltClear() completely! The clear-loop now clears
- ;* as many long-words in a row as possible. This should maximize
- ;* performance.
- ;*
- ;* V2.102 : CPUClear used to trash the window, if the size was chosen
- ;* very small, so I added a WaitBlit().
- ;* Thanks to Franz Schwarz for reporting the bug and Chris Hames
- ;* for giving me the blitter-problem-hint!
- ;*
- ;* V2.101 : NewBltClr() has been rewritten completely for even more
- ;* performance. NewBltClr() now uses the longword-loop only, if
- ;* the address of the memoryblock is longword-aligned, not if
- ;* the size is.
- ;*
- ;* V2.100 : released: Peter Simons (03-Okt-92)
- ;*
- ;* V2.024 : changed short branches from ".s" to Motorola's ".b"-style
- ;*
- ;* V2.023 : added security-check to catch odd numbers of byte to clear
- ;*
- ;* V2.022 : changed the way, the end of the "blit" is recognized from
- ;* >BCC< to >BNE<. This saved 8 byte.
- ;*
- ;* V2.021 : test for zero-length-calls works now with bytes/row-mode, too
- ;*
- ;* V2.020 : Added a delay before the memory of NewBltClr() will be freed,
- ;* because this could possibly crash the machine if the new
- ;* routine is used while CPUClear tries to remove it.
- ;*
- ;* V2.011 : The last version included a trashed revision-date!
- ;* Peter Simons (23-Aug-92)
- ;*
- ;* V2.010 : added cache-flushing-routines for 68040 compatiblity
- ;*
- ;* V2.000 : Final version! (??) released: Peter Simons (24-Jul-92)
- ;*
- ;* V1.042 : fixed bug in CPU-recognition
- ;*
- ;* V1.040 : Changed addressing mode in clear-loop! Again saved a few
- ;* bytes and cyles...
- ;*
- ;* V1.034 : I corrected a few typing-errors in the sourcecode
- ;*
- ;* V1.033 : I called SetFunction() with wrong parameters, which caused
- ;* the machine to crash immediately. (I'll never find out why it
- ;* worked on my Amiga all the time?? Don't ask! It's magic!)
- ;*
- ;* V1.032 : Added secure/unsecure switch
- ;*
- ;* V1.031 : released: Peter Simons (24-Jul-92)
- ;*
- ;* V1.030 : saved again 4 bytes by changing the addressing mode in the
- ;* clear loop
- ;*
- ;* V1.028 : NewBltClr won't crash the machine any longer if a blocksize
- ;* of ZERO is specified
- ;*
- ;* V1.027 : NewBltClr has only one exit-point now --> saves some bytes
- ;*
- ;* V1.026 : saved one swap-command in long-align-routine
- ;*
- ;* V1.025 : fixed minor bug: SIZE % 4 = 0 was NOT recognized by NewBltClr
- ;*
- ;* V1.020 : deleted opcodes in size-calculation: clearing the upper word
- ;* was a waste, because MULU works only on WORD-size
- ;*
- ;* V1.011 : optimized output-routines and saved some bytes
- ;*
- ;* V1.010 : the way how the patch is installed, has been completely re-
- ;* written and is shorter and, in my eyes, system-friendlier...
- ;*
- ;* V1.006 : program won't crash, if no standard-output is available!
- ;* (for example, if started out of DME...)
- ;*
- ;* V1.005 : program checks for at least OS 2.04 and 68020 or higher
- ;*
- ;* V1.004 : changed program-output and added OS 2.0-version-string
- ;*
- ;* V1.003 : minor changes to the source-code
- ;* revision header added
- ;* changed to Macro68k-Assembler
- ;*
- ;* V1.002 : merged hunks --> program is position independent
- ;*
- ;* V1.001 : I continue development: Peter Simons (23-Jul-92)
- ;*
- ;* V1.000 : written by Oliver Wagner
- ;*
- ;* V0.000 : --- Initial release ---
- ;*
- ;*************************************************************************
- ;
- ;
-
- ;***************************************************************************
- ;* *
- ;* SEKTION: Labels, Macros, Switches, Structures *
- ;* *
- ;***************************************************************************
-
- ;-------------------------------------- Switches -----------
- MC68000
- EXEOBJ
- OBJFILE "RAM:CPUClr"
- NEWSYNTAX
-
- SECURECODE set 1 ; test everything that could possibly
- ; crash the machine
-
- SPECIAL40 set 0 ; flush copyback after clearing the memory
-
- ;-------------------------------------- Exec ---------------
- eb_AttnFlags equ $0128
- lib_Version equ $0014
-
- MEMF_PUBLIC equ 1<<0
- AF_68020 equ 1
-
- ;-------------------------------------- Labels -------------
- MACLIB "DATAS:Offsets.preass"
- KICKVERSION equ 37
-
- _DOSBase equr A5
- _GfxBase equr A4
- _NewBltClr equr A3
- _OutputHandle equr D7
-
- ;-------------------------------------- Macros -------------
- REVISION MACRO
- dc.b "3.100"
- ENDM
- REVDATE MACRO
- dc.b "20-Okt-92"
- ENDM
-
-
- ;***************************************************************************
- ;* *
- ;* SEKTION: Program *
- ;* *
- ;***************************************************************************
-
- START: move.l ($4).w,a6
- IFNE SECURECODE
- cmp.w #KICKVERSION,(lib_Version,a6) ; Kickstart 2.04+ ?
- bmi .ErrorExit
- btst #AF_68020,(eb_AttnFlags+1,a6) ; 68020+ ?
- beq .ErrorExit
- ENDC
- lea (dosname,PC),a1
- jsr (_LVOOldOpenLibrary,a6) ; open Dos-Library
- IFNE SECURECODE
- tst.l d0
- beq .ErrorExit
- ENDC
- move.l d0,_DOSBase
-
- lea (gfxname,PC),a1
- jsr (_LVOOldOpenLibrary,a6) ; open Graphics-Lib
- IFNE SECURECODE
- tst.l d0
- beq .CloseDosLib
- ENDC
- move.l d0,_GfxBase
-
- move.l _DOSBase,a6
- jsr (_LVOOutput,a6) ; get standard-
- move.l d0,_OutputHandle ; outputhandle
-
- move.l _OutputHandle,d1
- IFNE SECURECODE
- beq.b .SkipWrite
- ENDC
- lea (Header,PC),a0 ; write standard-
- move.l a0,d2 ; header
- moveq #Header_len,d3
- jsr (_LVOWrite,a6)
-
- .SkipWrite move.l (_LVOBltClear+2,_GfxBase),_NewBltClr ; is the patch
- cmp.l #'FAST',(new_ID,_NewBltClr) ; already installed?
- beq.b .RemovePatch ; Yep->remove
-
- ;-------------------------------------- install patch ------
-
- move.l #NewBltClr_len,d0
- moveq #MEMF_PUBLIC,d1
- move.l ($4).W,a6
- jsr (_LVOAllocVec,a6)
- IFNE SECURECODE
- tst.l d0 ; Can't allocate
- beq.b .CloseGfxLib ; buffer for new
- ENDC ; routine
- move.l d0,_NewBltClr
-
- lea (NewBltClr,PC),a0
- move.l _NewBltClr,a1 ; copy patch into
- move.l #NewBltClr_len,d0 ; reserved buffer
- jsr (_LVOCopyMem,a6)
-
- jsr (_LVOForbid,a6)
- move.l _GfxBase,a1
- move.w #_LVOBltClear,a0 ; patch OS-function
- move.l _NewBltClr,d0
- jsr (_LVOSetFunction,a6)
- move.l d0,(new_OldBltClr,_NewBltClr) ; save old vector
- jsr (_LVOCacheClearU,a6) ; flush caches for
- jsr (_LVOPermit,a6) ; '40 compatiblity
-
- lea (Install,PC),a0 ; give feedback :-)
- moveq #Install_len,d3
- bra.b .exit
-
- ;-------------------------------------- remove patch -------
- .RemovePatch move.l _GfxBase,a1
- move.w #_LVOBltClear,a0
- move.l (new_OldBltClr,_NewBltClr),d0
- move.l ($4).W,a6
- jsr (_LVOSetFunction,a6) ; replace old
- move.l d0,a2 ; function and
- ; release memory
- move.l _DOSBase,a6
- moveq #100,d1
- jsr (_LVODelay,a6)
-
- move.l a2,a1
- move.l ($4).W,a6
- jsr (_LVOFreeVec,a6)
-
- move.l _DOSBase,a6
- lea (Remove,PC),a0
- moveq #Remove_len,d3
-
- ;-------------------------------------- exit gracefully ----
-
- .exit move.l _OutputHandle,d1
- IFNE SECURECODE
- beq.b .CloseGfxLib
- ENDC
- move.l a0,d2
- move.l _DOSBase,a6
- jsr (_LVOWrite,a6)
-
- move.l _OutputHandle,d1
- lea (Returns,PC),a0
- move.l a0,d2
- moveq #Returns_len,d3
- jsr (_LVOWrite,a6)
-
- .CloseGfxLib move.l _GfxBase,a1
- move.l ($4).W,a6 ; close resources
- jsr (_LVOCloseLibrary,a6) ; and leave
-
- .CloseDosLib move.l _DOSBase,a1
- jsr (_LVOCloseLibrary,a6)
-
- .ErrorExit moveq #0,d0
- rts
-
-
- ;***************************************************************************
- ;* *
- ;* SEKTION: new BltClear()-Routine *
- ;* *
- ;***************************************************************************
- NewBltClr: ; A1=&MemBlock A6=&GraphicsLibraryBase
- ; D0=bytecount D1=flags
-
- move.l d2,a0 ; save register
- btst #1,d1 ; bytes per row?
- beq.b .ByteSize ; Nope -> length is alright
- move.l d0,d2 ; Yep -> calc size of block
- swap d2
- mulu.w d2,d0
- .ByteSize bclr #0,d0 ; only even number of bytes
- tst.l d0 ; bytecount > 0 ?
- beq.b .finished ; Nope -> Exit!
- moveq #0,d2 ; clear memory or fill with
- btst #2,d1 ; pattern??
- beq.b .DataOK
- move.l d1,d2
- swap d1 ; --> fill with pattern
- move.w d1,d2
- .DataOK jsr (_LVOWaitBlit,a6) ; syncronisation!
-
- btst #1,d0
- beq.b .LongSize
- move.w a1,d1
- btst #1,d1
- bne.b .WordNotEasy
-
- subq.l #2,d0
- beq.b .GoOn1
- ... move.l d2,(a1)+ ; blocksize word-aligned
- subq.l #4,d0 ; memoryblock long-aligned
- bne.b ...
- .GoOn1 move.w d2,(a1)+
- bra.b .finished
-
- .WordNotEasy move.w d2,(a1)+ ; blocksize word-aligned
- subq.l #2,d0 ; memoryblock word-aligned
- beq.b .finished
- ... move.l d2,(a1)+
- subq.l #4,d0
- bne.b ...
- bra.b .finished
-
- .LongSize move.w a1,d1
- btst #1,d1
- bne.b .LongNotEasy
-
- ... move.l d2,(a1)+ ; blocksize and memoryblock
- subq.l #4,d0 ; both long-aligned
- bne.b ...
-
- .finished move.l a0,d2
- IFNE SPECIAL40
- pea (a6)
- move.l ($4).w,a6
- jsr (_LVOCacheClearU,a6) ; write back memory on '40
- move.l (SP)+,a6
- ENDC
- rts
-
- .LongNotEasy move.w d2,(a1)+
- subq.l #4,d0 ; long-aligned blocksize
- bmi.b .finished ; word-aligned memoryblock
- ... move.l d2,(a1)+
- subq.l #4,d0
- bne.b ...
- move.w d2,(a1)+
- bra.b .finished
-
- cnop 0,4
- new_ID equ (*-NewBltClr) ; Offsets for routine-ID and
- .ID dc.l "FAST" ; buffer for OldBltClr
- new_OldBltClr equ (*-NewBltClr)
- .OldBltClr dc.l 0
-
- NewBltClr_len equ (*-NewBltClr) ; length of routine
-
- ;***************************************************************************
- ;* *
- ;* SEKTION: Daten, Zeiger *
- ;* *
- ;***************************************************************************
-
- gfxname dc.b "graphics.library",0
- dosname dc.b "dos.library",0
- IFNE SECURECODE
- Header dc.b $9B,"1;33",$6D
- dc.b "$VER: CPUClr"
- IFNE SPECIAL40
- dc.b "40"
- ENDC
- dc.b " "
- REVISION
- dc.b " ("
- REVDATE
- dc.b ")"
- dc.b $9B,$6D
- dc.b " coding by Peter Simons",$0A
- Header_len equ (*-Header)
- ELSE
- dc.b "$VER: "
- Header dc.b "CPUClr"
- IFNE SPECIAL40
- dc.b "40"
- ENDC
- dc.b " "
- REVISION
- dc.b ": "
- Header_len equ (*-Header)
- ENDC
-
- Install dc.b "Installed"
- Install_len equ (*-Install)
- Remove dc.b "Removed"
- Remove_len equ (*-Remove)
- Returns dc.b "...",$0A,$0A
- Returns_len equ (*-Returns)
-
- END
-